/*!
    \copyright  Copyright (c) 2025 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \defgroup   accessory_device_service Accessory Device Service
    @{
         \ingroup    services
         \brief      A service that provides procedures for connecting and managing
                     connections to accessory devices.
    
     # Overview
    
         This service is mainly concerned with managing the connection to a accessory devices.
         Example: Charger case, Ring etc.
         At the moment we support only connections initiated from the remote (accessory).
    
     ## Remote Connections
    
         Remote connections will be detected by this accessory device service and notified to
         any clients that have registered for notifications.
    
         For the accesory to initiate a connection the local device must first be
         connectable - there are functions in this service to control whether the local
         device is connectable or not. (Currently not implemented)

     ## Connection Status
    
         If the connection status changes for any reason, e.g. link-loss or the handset
         has initiated a disconnect, it will be notified to any clients that have
         registered for notifications. (Currently not implemented)

*/

#ifndef ACCESSORY_DEVICE_SERVICE_H_
#define ACCESSORY_DEVICE_SERVICE_H_

#include <message.h>
#include <bdaddr.h>
#include "domain_message.h"

/*! \brief Different types of accessories */
typedef enum
{
    ACCESSORY_DEVICE_SERVICE_DEVICE_TYPE_UNKNOWN,
    ACCESSORY_DEVICE_SERVICE_DEVICE_TYPE_CHARGER_CASE,
    ACCESSORY_DEVICE_SERVICE_DEVICE_TYPE_RING
} accessory_device_service_device_type_t;

/*! \brief Events sent by accessory module to other modules. */
typedef enum
{
    /*! An accessory device connected */
    ACCESSORY_DEVICE_SERVICE_CONNECTED_IND = ACCESSORY_DEVICE_SERVICE_MESSAGE_BASE,

    /*! An accessory device disconnected. */
    ACCESSORY_DEVICE_SERVICE_DISCONNECTED_IND,

    /*! This must be the final message */
    ACCESSORY_DEVICE_SERVICE_MESSAGE_END
} accessory_device_service_msg_t;

/*! \brief Status codes for the accessory device service. */
typedef enum
{
    ACCESSORY_DEVICE_SERVICE_STATUS_SUCCESS,
    ACCESSORY_DEVICE_SERVICE_STATUS_FAILED,
    ACCESSORY_DEVICE_SERVICE_STATUS_DISCONNECTED,
    ACCESSORY_DEVICE_SERVICE_STATUS_LINK_LOSS,
} accessory_device_service_status_t;

/*! \brief Notification that an accessory has connected. */
typedef struct
{
    /*! Address of the accessory. */
    tp_bdaddr tp_addr;
} ACCESSORY_DEVICE_SERVICE_CONNECTED_IND_T;

/*! \brief Notification that an accessory has disconnected. */
typedef struct
{
    /*! Address of the accessory. */
    tp_bdaddr tp_addr;

    /*! Reason for the disconnect */
    accessory_device_service_status_t status;
} ACCESSORY_DEVICE_SERVICE_DISCONNECTED_IND_T;

/*! \brief Initialise the accessory device service module

    \param task Unused

    \return Always TRUE
*/
bool AccessoryDeviceService_Init(Task task);

/*! \brief Adds the given accessory device address into accessory list managed by accessory device service.

           Note: Before connecting/pairing to any new accessory device, the caller must inform the accessory device 
           details to the accessory device service by calling this API. This information will be used by accessory device service 
           to filter and accept incoming ACL connection from accessories and helps it to avoid processing handset connections.

    \param tp_addr Public address of the device to add
    \param type Type of the accessory

    \return TRUE if successfully added into the list, FALSE if it is already in the list or list is full.
*/
bool AccessoryDeviceService_AddDeviceInfo(tp_bdaddr *tp_addr, accessory_device_service_device_type_t type);

/*! \brief Remove the given address from accessory list

           This API will return FALSE if the device is already connected and it will not initiate disconnect.

    \param tp_addr Address of the device to remove.

    \return TRUE if remove was successful. FALSE if the given address is not in the list or if the device is connected.
*/
bool AccessoryDeviceService_RemoveDeviceInfo(tp_bdaddr *tp_addr);

/*! \brief Check if given address is in the accessory list

    \param tp_addr Address of the device to check

    \return TRUE if the given device is in accessory list, FALSE otherwise.
*/
bool AccessoryDeviceService_IsAccessoryDevice(tp_bdaddr *tp_addr);

/*! \brief Get the accessory device type associated with the given address

    \param tp_addr Address of the device to check

    \return Type of accessory device. If unable to find a matching entry, returns ACCESSORY_DEVICE_SERVICE_DEVICE_TYPE_UNKNOWN.
*/
accessory_device_service_device_type_t AccessoryDeviceService_GetDeviceType(tp_bdaddr *tp_addr);

/*! \brief Disconnects an accessory device based on the provided transport tp_bdaddr address using provided reason code.

    This function retrieves the accessory device entry corresponding to the given transport address,
    checks if the device is currently connected, and if so, releases the connection with the specified reason code.

    \param tp_addr Pointer to the transport tp_bdaddr address of the device to be disconnected.
    \param reason_code The reason code for the disconnection.

    \return TRUE if disconnect request is sent, FALSE otherwise
*/
bool AccessoryDeviceService_DisconnectAccessory(tp_bdaddr *tp_addr, uint8 reason_code);

/*! \brief Sets the priority of an accessory device based on the provided transport tp_bdaddr address.

    This function retrieves the accessory device entry corresponding to the given transport address,
    checks if the device entry exists, and if so, sets the priority to low or high based on the provided boolean value.

    \param tp_addr Pointer to the transport tp_bdaddr address of the device.
    \param is_low_priority Boolean value indicating whether to set the device to low priority.

    \return TRUE if the priority was successfully set, FALSE otherwise.
 */
bool AccessoryDeviceService_SetPriorityForAccessory(tp_bdaddr *tp_addr, bool is_low_priority);

/*! Registers accessory device service as Persistant Device Data user */
void AccessoryDeviceService_RegisterAsPersistentDeviceDataUser(void);

/*! \brief Register a task to receive notifications from accessory device service.

    Once registered, #client_task will receive #accessory_device_service_msg_t messages.

    \param client_task Task to register to receive accessory device service notifications.
*/
void AccessoryDeviceService_ClientRegister(Task client_task);

/*! \brief Un-register a task that is receiving notifications from accessory device service.

    If the task is not currently registered then nothing will be changed.

    \param client_task Task to un-register from accessory device service notifications.
*/
void AccessoryDeviceService_ClientUnregister(Task client_task);

#endif /* ACCESSORY_DEVICE_SERVICE_H_ */
